#include <stdio.h>
#include <stdlib.h>
#include "abcrypto.h"

#include "cipher.h"
#include "hash.h"

static struct abcrypto_skcipher *get_skcipher(uint16_t alg)
{
	switch (alg) {
	case ABCRYPTO_CIPHER_AES_128_ECB:
	case ABCRYPTO_CIPHER_AES_128_CBC:
	case ABCRYPTO_CIPHER_AES_128_CTR:
	case ABCRYPTO_CIPHER_AES_128_CFB:
	case ABCRYPTO_CIPHER_AES_128_OFB:
	case ABCRYPTO_CIPHER_AES_192_ECB:
	case ABCRYPTO_CIPHER_AES_192_CBC:
	case ABCRYPTO_CIPHER_AES_192_CTR:
	case ABCRYPTO_CIPHER_AES_192_CFB:
	case ABCRYPTO_CIPHER_AES_192_OFB:
	case ABCRYPTO_CIPHER_AES_256_ECB:
	case ABCRYPTO_CIPHER_AES_256_CBC:
	case ABCRYPTO_CIPHER_AES_256_CTR:
	case ABCRYPTO_CIPHER_AES_256_CFB:
	case ABCRYPTO_CIPHER_AES_256_OFB:
		return mbed_cipher();
	default:
		return NULL;
	}

	return NULL;
}

static struct abcrypto_auth *get_auth(uint16_t alg)
{
	if ((alg & 0xff00) == 0x0100) {
		if ((alg & 0xf0) == 0x00) {
			switch (alg & 0xf) {
			case ABCRYPTO_AUTH_ALG_MD5:
			case ABCRYPTO_AUTH_ALG_SHA1:
			case ABCRYPTO_AUTH_ALG_SHA224:
			case ABCRYPTO_AUTH_ALG_SHA256:
			case ABCRYPTO_AUTH_ALG_SHA384:
			case ABCRYPTO_AUTH_ALG_SHA512:
			case ABCRYPTO_AUTH_ALG_SHA3_224:
			case ABCRYPTO_AUTH_ALG_SHA3_256:
			case ABCRYPTO_AUTH_ALG_SHA3_384:
			case ABCRYPTO_AUTH_ALG_SHA3_512:
				/* hash*/
				return mbed_hash();
			default:
				break;
			}

		} else if ((alg & 0xf0) == 0x10) {
			switch (alg & 0xf) {
			case ABCRYPTO_AUTH_ALG_MD5:
			case ABCRYPTO_AUTH_ALG_SHA1:
			case ABCRYPTO_AUTH_ALG_SHA224:
			case ABCRYPTO_AUTH_ALG_SHA256:
			case ABCRYPTO_AUTH_ALG_SHA384:
			case ABCRYPTO_AUTH_ALG_SHA512:
			case ABCRYPTO_AUTH_ALG_SHA3_224:
			case ABCRYPTO_AUTH_ALG_SHA3_256:
			case ABCRYPTO_AUTH_ALG_SHA3_384:
			case ABCRYPTO_AUTH_ALG_SHA3_512:
				/* hash*/
				return mbed_hmac();
			default:
				break;
			}
		}
	}

	return NULL;
}

static struct abcrypto_instance mbedtls = { .name = "mbedtls",
					    .get_skcipher = get_skcipher,
					    .get_auth = get_auth };

/*范围是 0 到 100，数值越小，函数执行的优先级越高*/
static __attribute__((constructor(200))) void _register_mbedtls(void)
{
	int ret = register_instance(&mbedtls);
	if (ret) {
		fprintf(stderr, "fill mbedtls failed\r\n");
	} else {
		fprintf(stdout, "fill mbedtls ok\r\n");
	}
}
